package com.syh.jn.scm.infrastructure.repository.impl.supplier.base;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.infrastructure.repository.AbstractAggregateRepository;
import com.syh.core.expction.DataModelException;
import com.syh.core.expction.UnexpectedlyException;
import com.syh.jn.scm.domain.supplier.entity.base.Project;
import com.syh.jn.scm.domain.supplier.entity.base.ProjectItem;
import com.syh.jn.scm.domain.supplier.repository.base.ProjectRepository;
import com.syh.jn.scm.dto.supplier.base.project.ProjectVo;
import com.syh.jn.scm.infrastructure.repository.model.base.ProjectItemModel;
import com.syh.jn.scm.infrastructure.repository.model.base.ProjectModel;
import com.syh.jn.scm.infrastructure.repository.utils.SQLAliasGenerateUtil;
import com.syh.jn.scm.infrastructure.wrapper.BaseResolve;
import com.syh.jn.scm.infrastructure.wrapper.ResolveToSQL;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 运营项目关联商品
 */
@Repository
public class ProjectRepositoryImpl extends AbstractAggregateRepository<Project, ProjectModel, Long> implements ProjectRepository {

  @Override
  public Project getById(Long id) {
    Project project = super.getById(id);
    project.setItems(this.getItemsById(id));
    return project;
  }
  public List<ProjectItem> getItemsById(Long id) {
    String hql = "from ProjectItemModel model where model.projectId = ?";
    List<ProjectItemModel> itemList = (List<ProjectItemModel>) this.hibernateTemplate.find(hql, id);
    return transformItems(itemList);
  }

  @Override
  public Long add(Project project) {
    //取到父类的目录树
    ProjectModel father = new ProjectModel();
    if (project.getSupId() != null) {
      father = super.hibernateTemplate.get(ProjectModel.class, project.getSupId());
      if (father == null) {
        throw new DataModelException("父级分类不存在");
      }
    }

    ProjectModel model = new ProjectModel();
    ExtBeanUtils.copyProperties(project, model);
    super.hibernateTemplate.save(model);
    StringBuffer catalogCodeStr = ExtStringUtils.isEmpty(father.getCatalogCode()) ? new StringBuffer() : new StringBuffer(father.getCatalogCode()).append("-");
    model.setCatalogCode(catalogCodeStr.append(model.getId()).toString());
    return model.getId();
  }

  @Override
  public void update(Project project) {
    //取到父类的目录树
    ProjectModel father = new ProjectModel();
    if (project.getSupId() != null) {
      father = super.hibernateTemplate.get(ProjectModel.class, project.getSupId());
      if (father == null) {
        throw new DataModelException("父级分类不存在");
      }
    }
    ProjectModel model = super.hibernateTemplate.get(ProjectModel.class, project.getId());
    ExtBeanUtils.copyProperties(project, model);
    super.hibernateTemplate.update(model);
    StringBuffer catalogCodeStr = ExtStringUtils.isEmpty(father.getCatalogCode()) ? new StringBuffer() : new StringBuffer(father.getCatalogCode()).append("-");
    model.setCatalogCode(catalogCodeStr.append(model.getId()).toString());
  }

  @Override
  public void updateStatus(Project project) {
    super.update(project);
    List<Project> subProjects = Collections.EMPTY_LIST;
    if(project.getParents() != null && project.getParents().size() > 0)
      subProjects = project.getParents();
    if(project.getSubProjects() != null && project.getSubProjects().size() > 0)
      subProjects = project.getParents();

    subProjects.forEach(subProject ->{
      super.update(subProject);
    });
  }

  /**
   * 重写remove
   * @param project
   */
  @Override
  public void remove(Project project){
    //删除运营项目基础数据
    super.remove(project);
    this.removeItemsById(project.getId());
  }
  public void removeItemsById(Long id){
    String hql = "from ProjectItemModel model where model.projectId = ?";
    List<ProjectItemModel> itemModelList = (List<ProjectItemModel>) this.hibernateTemplate.find(hql, id);
    itemModelList.stream().forEach(item -> {
      this.hibernateTemplate.delete(item);
    });
  }

  protected SQL getViewSql() {
    return new SQL() {{
      SELECT(
              SQLAliasGenerateUtil.aliasGenerate(ProjectModel.class, "project", null,new String[]{"supName"}),
              "project2.NAME AS supName"
      );
      FROM(getModelTableName(ProjectModel.class)+" project");
      LEFT_OUTER_JOIN(
              getModelTableName(ProjectModel.class)+" project2 on project.SUP_ID = project2.ID"
      );
    }};
  }

  protected BaseResolve getViewWrapperResolve(Wrapper wrapper) {
    HashMap<String,String> weMap = new HashMap<>();
    weMap.put("id", "project.ID");
    weMap.put("name", "project.NAME");
    weMap.put("status", "project.STATUS");
    weMap.put("code", "project.CODE");
    weMap.put("supId", "project.SUP_ID");
    weMap.put("catalogCode", "project.CATALOG_CODE");
    weMap.put("businessEntityId", "project.BUSINESS_ENTITY_ID");
    weMap.put("createTimeStamp", "project.CREATE_TIME_STAMP");
    ResolveToSQL parse = new ResolveToSQL(wrapper, (propertyName) -> {
      return weMap.get(propertyName);
    });
    return parse;
  }

  protected Class getViewObject() {
    return ProjectVo.class;
  }

  /**
   * 业务模型转领域模型
   * @param modelList
   * @return
   */
  protected List<ProjectItem> transformItems(List<ProjectItemModel> modelList) {
    List<ProjectItem> voList = modelList.stream().map((model) -> {
      return this.transformItem(model);
    }).collect(Collectors.toList());
    return voList;
  }

  /**
   * 业务模型转领域模型
   * @return
   */
  protected ProjectItem transformItem(ProjectItemModel model) {
    ProjectItem entity = null;
    try {
      entity = new ProjectItem();
      ExtBeanUtils.copyProperties(model, entity);
    } catch (Exception e) {
      throw new UnexpectedlyException("初始化 entity 异常");
    }
    return entity;
  }
}
